#![allow(non_snake_case)]
use std::collections::HashMap;

use icondata as i;
// 展示导入kpi所有指标状态的过程
use leptos::prelude::*;
use leptos_icons::*;
use serde_json::{Map, Value};
use shq_web_controls::{ToastPosition, ToasterProvider};
use thaw_utils::ArcOneCallback;
use crate::{components::{ButtonList, DataRange}, layout::upload::UploadExcel, report::Report};
use leptos::task::spawn_local;
use crate::{components::{CommonPage}};


#[component]
pub fn KpiImport(menu_id: u32) -> impl IntoView {
    let display_import: RwSignal<bool> = RwSignal::new(false);
    let is_refresh: RwSignal<bool> = RwSignal::new(false);
    let file_progress_list: RwSignal<HashMap<String, String>> = RwSignal::new(HashMap::new());
    // 创建自定义按钮回调函数
    let jd = RwSignal::new(i32::default());
    let custom_button_callback = ArcOneCallback::new(move |_| {
        display_import.set(true)
    });
    let on_tolbar_params_change = ArcOneCallback::new(move |params: HashMap<String, String>| {
        if let Some(jd_str) = params.get("jd") {
            if let Ok(jd_val) = jd_str.parse::<i32>() {
                jd.set(jd_val);
            }
        }
    });
    let conf_name = RwSignal::new(String::from("kpi_import_lhzb"));
    let zbid = RwSignal::new(String::from("0".to_string()));
    let title_name = RwSignal::new(String::new());
    let on_row_select_change = ArcOneCallback::new(move |selected_rows: Option<Map<String, Value>>| {
        if let Some(rows) = selected_rows {
            if let Some(Value::String(conf_name_value)) = rows.get("confname") {
                conf_name.set(conf_name_value.clone());
            }
            if let Some(Value::Number(zbid_value)) = rows.get("zbid") {
                if let Some(int_zbid) = zbid_value.as_i64() {
                    zbid.set(int_zbid.to_string());
                }
            }
            if let Some(Value::String(title_name_value)) = rows.get("zbid__dict") {
                title_name.set(title_name_value.clone());
            }
        }
    });
    let on_upload = move |file_name: String| {
        spawn_local(async move {
            let fname=if file_name.len()>36 {
                file_name[36..].to_owned()
            } else {
                file_name.to_owned()
            };
            let res = kpi_import_excel_data(menu_id,jd.get(), None, file_name).await;
            match res {
                Ok(count) => file_progress_list.update(|fps| {
                    fps.insert(fname, format!("导入成功{}条数据", count));
                    display_import.set(false);
                    is_refresh.set(true);
                }),
                Err(err) => file_progress_list.update(|fps| {
                    fps.insert(fname, format!("导入失败: {}", err));
                }),
            }
        })
    };
    let import_view = move || {
        if display_import.get() {
            Some(view! {
                <dialog id="data_import_modal" class="modal modal-open z-50">
                    <div class="modal-box overflow-hidden">
                        <button class="absolute right-2 top-2" on:click=move|_|{
                            display_import.set(false);
                            file_progress_list.set(HashMap::new());
                        }>
                            <Icon icon=i::AiCloseCircleOutlined width="20" height="20"/>
                        </button>
                        <h3 class="text-lg font-bold">KPI数据导入</h3>
                        <UploadExcel file_progress_list  on_upload/>
                    </div>
                </dialog>
            })
        } else {
            None
        }
    };
    // 定义自定义按钮
    let custom_buttons = {
        let mut bl=ButtonList::new();
        bl.add_custom(
            "KPI数据导入".to_string(),
            Some(i::AiCloudUploadOutlined),
            None,
            None,
            DataRange::None,
            Vec::new(),
            custom_button_callback,
        );
        bl
    };
    let report_view = move || {
        let title =MaybeProp::derive(move || Some(title_name.get()));
        let params= MaybeProp::derive(move || Some(vec![
            ("jd".to_string(), jd.get_untracked().to_string()),
            ("zbid".to_string(), zbid.get_untracked()),
        ]));
        view! {
            <Report menu_id rept_name=conf_name.get() params title/>
        }
    };
    view! {
        <div class="flex flex-1 gap-4 min-h-1 p-4 pb-2 w-full h-full  overflow-hidden">
            <Suspense fallback=|| view! { <progress class="progress w-56"></progress> }>
                <CommonPage menu_id conf_name="kpi_import" custom_buttons on_tolbar_params_change on_row_select_change is_refresh />
                {report_view}
                <ToasterProvider position=ToastPosition::TopStart>
                    {import_view}
                </ToasterProvider>
            </Suspense>
        </div>
    }
}
#[server(ImportExcelData, "/api/protect")]
pub async fn kpi_import_excel_data(
    menu_id: u32,
    jd: i32,
    paras_vals: Option<String>,
    excel_file_name: String,
) -> Result<u64, ServerFnError> {
    use crate::auth::get_user_context_with_auth;
    let user = get_user_context_with_auth(menu_id, shq_common::prelude::AuthType::Import).await?;
    let mut paras_map: HashMap<String, String> = HashMap::new();
    if let Some(paras_vals) = paras_vals {
        paras_map = serde_json::from_str(&paras_vals).unwrap();
    }
    paras_map.insert("jd".to_string(), jd.to_string());
    let excel_reader = shq_common::prelude::ExcelReader::from_file_name(&excel_file_name)?;
    let name = shq_common::prelude::ExcelReader::get_cell_value(&excel_reader, 0, 0).await?;
    let name = name.to_string();
    let kpi_import_conf_names = shq_pas_backend::kpi_import_conf_name(jd, &name)
        .await
        .map_err(|e| ServerFnError::new(format!("获取KPI导入配置错误：{}", e)))?;
    let mut total_count = 0;
    let mut last_error = None;
    for kpi_conf in kpi_import_conf_names.iter() {
        let mut current_paras_map = paras_map.clone();
        current_paras_map.insert("zbid".to_string(), kpi_conf.zbid.to_string());
        let ps = shq_pas_backend::PageService::new(&kpi_conf.conf_name, user.user_id, menu_id);
        use crate::auth::get_user_context;
        let user=get_user_context().await.or_else(|err|{
            Err(ServerFnError::new(format!("获取用户信息失败：{}", err)))
        })?;
        match ps.import_excel(current_paras_map, &excel_reader).await {
            Ok(count) => {
                shq_pas_backend::kpi_update_log(user.user_id, kpi_conf.zbid,jd).await.map_err(|e| ServerFnError::new(format!("更新KPI导入日志错误：{}", e)))?;
                total_count += count;
            }
            Err(e) => {
                log::error!("导入配置 {} 失败: {}", kpi_conf.conf_name, e);
                last_error = Some(e);
            }
        }
    }
    if total_count > 0 {
        Ok(total_count)
    } else if let Some(e) = last_error {
        Err(ServerFnError::ServerError(e.to_string()))
    } else {
        Err(ServerFnError::ServerError("没有找到可导入的配置".to_string()))
    }
}